<?php
namespace app\api\controller\v1;
include_once APP_PATH . 'api/common.php';
use app\common\controller\Api;
use app\common\model\ClassStudent;
use app\common\model\Student;
use TencentCloud\Ess\V20201111\Models\DeleteSealPoliciesRequest;
use think\Db;
use think\Request;
use think\Log;
use app\admin\model\Favorites;
use app\admin\model\School;
use app\admin\model\Ocation;
use app\admin\model\Classes;
use app\admin\model\Article;

class My extends Api
{
    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';

    public function getInfo()
    {
        $user = $this->auth->getUser();

        $userInfo =\app\admin\model\User::alias('u')
            ->field('u.*, c.name as class_name, c.id as class_id')
            ->join('eb_class_student cs', 'u.id = cs.student_id', 'LEFT')
            ->join('eb_classes c', 'cs.classes_id = c.id', 'LEFT')
            ->where('u.id', $user['uid'])
            ->find();

        if (!$userInfo) {
            $this->error('用户不存在');
        }

        // 使用UserFilter过滤用户基本信息
        $filteredUserInfo = $this->UserFilter($userInfo);

        // 保留额外的班级信息
        $filteredUserInfo['class_name'] = $userInfo['class_name'];
        $filteredUserInfo['class_id'] = $userInfo['class_id'];

        // 获取学分信息
        $credit = \app\admin\model\Credits::where('user_id', $user['uid'])->sum('value');
        $filteredUserInfo['credit'] = $credit ?: 0;

        // 获取已报班级数量
        $classCount =  \app\admin\model\Student::alias('s')
            ->where('student_id', $user['uid'])
            ->count();
        $filteredUserInfo['class_count'] = $classCount;

        $this->success('获取成功', $filteredUserInfo);
    }

    // 报名缴费
    public function applyPayList()
    {
        $user = $this->auth->getUser();
        $userId = $user['uid'];
        $type=$this->request->param('type','');

        // 首先检查并更新超过3小时未支付的报名记录状态为5（超时不支付不可见）
        $timeoutTime = date('Y-m-d H:i:s', strtotime('-3 hours'));
        Db::name('eb_apply_form_item')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->where('pay_status', 0)
            ->where('pay_time', null)
            ->where('create_time', '<', $timeoutTime)
            ->update(['status' => 5]);

        // 获取排序参数
        $orderBy = $this->request->param('order_by', 'update_time');
        $orderType = $this->request->param('order_type', 'desc');

        // 获取报名缴费信息
        $applyPayList = Db::name('eb_apply_form_item');
        if($type=='yuye'){
            $applyPayList = $applyPayList->alias("f")
                ->join("fa_order o", "f.order_id = o.id","left")
                ->join('fa_refund refund','o.refund_id=refund.id','left')
                ->join("eb_classes c", "f.classes_type=1 and f.classes_id = c.id","left")
                ->join("fa_ocation_class c2", "f.classes_type=2 and f.classes_id = c2.id","left")
                ->join("fa_community_course_config c3", "c2.subject_lv = c3.id","left")
                ->join("fa_ocation o2", "c2.ocation_id = o2.id","left")
                ->join("fa_course_table_autoplan a", "c2.publicwelfare_id = a.publicwelfare_id and c2.id = a.classes_id and c2.classes_type=2 and a.subject_lv=c2.subject_lv","left")
                ->where("f.user_id", $userId)
                ->where("f.status", 1)
                ->where("f.pay_status", 0)
                ->where("f.classes_type",2)
                ->field("a.id as t_id,f.*,o.order_sn,o.out_trade_no,o.refund_status,refund.refund_fee,refund.update_time as refund_time,c2.name as class_name,o2.address as address,c3.name as subject_name,o.amount as amount,o.payment_status,o.pay_time,o.pay_type,o.pay_channel_id");
        }else{
            $applyPayList = $applyPayList->alias("f")
                ->join("fa_order o", "f.order_id = o.id","left")
                ->join('fa_refund refund','o.refund_id=refund.id','left')
                ->join("eb_classes c", "f.classes_type=1 and f.classes_id = c.id","left")
                ->join("fa_ocation_class c2", "f.classes_type=2 and f.classes_id = c2.id","left")
                ->join("fa_community_course_config c3", "c2.subject_lv = c3.id","left")
                ->join("fa_ocation o2", "o2.id = c.ocation_id","left")
                ->join("fa_course_table_autoplan a", "c.id=a.classes_id and c.classes_type=1","left")
                ->where("f.user_id", $userId)
                ->where(function($query) {
                    $query->where("f.status", 1)->whereOr("f.pay_status", 4);
                })
                ->where("o.amount",">",0)
                ->field("f.id as apply_item_id,f.pay_status as apply_item_pay_status,o.refund_status,refund.refund_fee,refund.update_time as refund_time,f.*,c.ocation_id as c_ocation_id,o2.id as ocation_id,o.order_sn,o.out_trade_no,c.name as class_name,o2.address as address,c3.name as subject_name,date(a.date) as start_date,o.amount as amount,o.payment_status,o.pay_time,o.pay_type,o.pay_channel_id");
        }

        // 添加排序条件
        // 根据不同的排序字段进行排序
        if ($orderBy === 'update_time') {
            // 使用简单的多字段排序，先按订单更新时间，再按退款时间，最后按报名项目更新时间
            $applyPayList = $applyPayList->order("o.update_time " . $orderType . ", refund.update_time " . $orderType . ", f.update_time " . $orderType);
        } else {
            // 其他字段的排序
            $applyPayList = $applyPayList->order($orderBy . ' ' . $orderType);
        }

        // 添加分组条件，将同一个订单号和同一个班级的记录合并
        $applyPayList = $applyPayList->group("o.order_sn, f.classes_id");

        // 获取分页参数
        $page = $this->request->param('page', 1, 'intval');
        $pageSize = 20; // 每页显示20条数据

        // 执行分页查询
        $applyPayList = $applyPayList->paginate($pageSize, false, ['page' => $page]);

        if (!$applyPayList) {
            $this->error('没有报名缴费信息');
        }

        // 获取分页数据
        $items = $applyPayList->items();

        // 格式化数据
        foreach ($items as &$item) {
            $item['title'] = model("\app\common\model\Classes")->getClasses_idTextAttr($item['classes_id'],$item);
            $item['school_name'] = model("\app\admin\model\School")->getSchool_idTextAttr($item['school_id'],$item);
            $item['pay_status'] = $item['pay_status'] == 1 ? '已支付' : ($item['pay_status'] == 4 ? '已退费' : '待支付');
            $item['payment_status'] = $item['payment_status'] == 1 ? '已支付' : '待支付';
            $item['pay_time'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '';
            $item['refund_time'] = $item['refund_time'] ? date('Y-m-d H:i:s', $item['refund_time']) : '';

            // 添加最新的更新时间，用于前端排序
            $item['update_time'] = max(
                $item['update_time'] ?? 0,
                $item['pay_time'] ? strtotime($item['pay_time']) : 0,
                $item['refund_time'] ? strtotime($item['refund_time']) : 0
            );
        }

        // 构建返回数据
        $result = [
            'list' => $items,
            'total' => $applyPayList->total(),
            'current_page' => $applyPayList->currentPage(),
            'last_page' => $applyPayList->lastPage(),
            'per_page' => $applyPayList->listRows()
        ];

        $this->success('获取报名缴费项目成功', $result);
    }

    /**
     * 申请退款功能
     * 此函数用于处理用户提交的退款申请
     */
    public function applyRefund()
    {
        $user = $this->auth->getUser(true);
        if(empty($user)){
            return $this->error('请先登录', null, 401);
        }

        // 获取请求参数
        $params = $this->request->param();
        $order_id = $params['apply_item_id'] ?? 0;
        $refund_reason = $params['refund_reason'] ?? '';
        $refund_fee = $params['refund_fee'] ?? 0;
        // 查询订单信息
        $order = Db::name('order')
            ->where('id', $order_id)
            ->find();

        if(!$order){
            return $this->error('订单信息不存在', null, 404);
        }else{
            $apply_item_id=$order['apply_id'];
        }
        // 如果提供了报名项目ID，则查询报名项目信息
        if(!empty($apply_item_id)){
            $applyItem = Db::name('eb_apply_form_item')
                ->alias("f")
                ->join("fa_order o", "f.order_id = o.id","left")
                ->where('f.id', $apply_item_id)
                ->where('f.user_id', $user['uid'])
                ->field("f.id as apply_item_id,f.order_id,o.pay_status")
                ->find();

            if(!$applyItem){
                return $this->error('报名项目不存在', null, 404);
            }

            // 检查是否已支付
            if($applyItem['pay_status'] != 1){
                return $this->error('该订单未支付，无法退款', null, 400);
            }

            $order_id = $applyItem['order_id'];
        }



        // 检查订单状态
        if($order['status'] != 1){
            return $this->error('订单状态不允许退款', null, 400);
        }

        // 检查退款金额
        if(empty($refund_fee) || $refund_fee <= 0){
            $refund_fee = $order['amount'];
        }

        if($refund_fee > $order['amount']){
            return $this->error('退款金额不能大于订单金额', null, 400);
        }

        // 检查微信支付交易订单号是否存在且格式正确
        if(empty($order['pay_channel_id'])){
            return $this->error('订单支付信息不完整，无法退款', null, 400);
        }

        // 验证微信支付交易订单号格式（1-32位数字）
        if(!preg_match('/^\d{1,32}$/', $order['pay_channel_id'])){
            return $this->error('订单支付信息格式错误，无法退款', null, 400);
        }

        // 检查是否已经申请过退款
        $existingRefund = Db::name('refund')
            ->where('order_id', $order_id)
            ->where('status', 'in', [0, 1]) // 0:处理中, 1:成功
            ->find();
        $refundId=$existingRefund['id'] ?? 0;
        if($existingRefund){
            $refundStatus = $this->queryWechatRefundStatus($existingRefund['refund_no']);
            if(isset($refundStatus['refund_status']) && $refundStatus['refund_status'] == 'SUCCESS'){
                $this->finishRefund($refundId, $refundStatus, $order_id, $apply_item_id, $refund_fee);
                return $this->success('退款成功', $refundStatus);
            }
        }

        // 生成退款单号
        $refund_no = 'REFUND' . date('YmdHis') . mt_rand(1000, 9999);

        // 创建退款记录
        $refundData = [
            'refund_no' => $refund_no,
            'order_id' => $order_id,
            'user_id' => $user['uid'],
            'total_fee' => $order['amount'], // 订单总金额
            'refund_fee' => $refund_fee, // 退款金额
            'refund_reason' => $refund_reason,
            'status' => 0, // 0:处理中, 1:成功, 2:失败
            'create_time' => time(),
            'update_time' => time()
        ];

        // 如果提供了报名项目ID，则添加到退款记录中
        if(!empty($apply_item_id)){
            $refundData['apply_item_id'] = $apply_item_id;
        }

        $refundId = Db::name('refund')->insertGetId($refundData);

        try {
            // 查询微信退款状态
            $refundStatus = $this->queryWechatRefundStatus($refund_no);

            if(isset($refundStatus['refund_status']) && $refundStatus['refund_status'] == 'SUCCESS'){
                Db::name('refund')->where('id', $refundId)->update([
                    'status' => 1, // 退款成功
                    'refund_id' => $refundStatus['refund_id'] ?? '', // 微信退款单号
                    'update_time' => time(),
                    'refund_status' => $refundStatus['refund_status'], // 退款状态
                    'create_time' => strtotime($refundStatus['create_time']), // 微信退款创建时间
                    'out_refund_no' => $refundStatus['out_refund_no'] ?? '', // 商户退款单号
                    'out_trade_no' => $refundStatus['out_trade_no'] ?? '', // 商户订单号
                    'user_received_account' => $refundStatus['user_received_account'] ?? '', // 用户退款收款账户
                ]);

                // 更新订单状态
                Db::name('order')->where('id', $order_id)->update([
                    'status' => 4, // 已退款
                    'pay_status' => 4, // 已退款
                    'refund_id' => $refundStatus['refund_id'],
                    'refund_time' => time(),
                    'refund_status' => 'SUCCESS',
                    'refund_amount' => $refund_fee,
                ]);

                // 更新报名项目状态
                if(!empty($apply_item_id)){
                    Db::name('eb_apply_form_item')->where('id', $apply_item_id)->update([
                        'pay_status' => 4, // 退款成功
                        'status' => 0, // 退款成功
                    ]);
                }

                return $this->success('退款成功', $refundStatus);
            }
            else if(isset($refundStatus['refund_status']) && $refundStatus['refund_status'] == 'PROCESSING'){
                Db::name('refund')->where('id', $refundId)->update([
                    'status' => 3, // 退款处理中
                    'refund_id' => $refundStatus['refund_id'] ?? '', // 微信退款单号
                    'update_time' => time(),
                    'refund_status' => $refundStatus['status'], // 退款状态
                    'create_time' => strtotime($refundStatus['create_time']), // 微信退款创建时间
                    'out_refund_no' => $refundStatus['out_refund_no'] ?? '', // 商户退款单号
                    'out_trade_no' => $refundStatus['out_trade_no'] ?? '', // 商户订单号
                    'user_received_account' => $refundStatus['user_received_account'] ?? '', // 用户退款收款账户
                ]);

                return $this->success('申请已经成功，正在退款的过程中...', $refundStatus);
            }
            else if(isset($refundStatus['refund_status']) && $refundStatus['refund_status'] == 'FAILED'){
                Db::name('refund')->where('id', $refundId)->update([
                    'status' => 2, // 退款失败
                    'update_time' => time(),
                    'refund_status' => $refundStatus['refund_status'], // 退款状态
                    'create_time' => strtotime($refundStatus['create_time']), // 微信退款创建时间
                    'out_refund_no' => $refundStatus['out_refund_no'] ?? '', // 商户退款单号
                    'out_trade_no' => $refundStatus['out_trade_no'] ?? '', // 商户订单号
                    'refund_id' => $refundStatus['refund_id'] ?? '', // 微信退款单号
                    'user_received_account' => $refundStatus['user_received_account'] ?? '', // 用户退款收款账户
                ]);

                return $this->success('退款申请已经提交，退款金额将在1-3个工作日内原路返回', $refundStatus);
            }
            else{
                // 调用微信退款API
                $result = $this->processWechatRefund(
                    $order['pay_channel_id'], // 微信支付交易订单号
                    $refundData['refund_no'], // 商户退款单号
                    $order['amount'], // 订单金额
                    $refund_fee // 退款金额
                );

                return $this->success('退款申请已提交，请等待处理', [
                    'refund_id' => $refundId,
                    'refund_no' => $refund_no,
                    'status' => 0,
                    'status_text' => '退款处理中'
                ]);
            }

        } catch (\Exception $e) {
            // 处理特定错误情况：订单已退款
            if($e->getMessage() == '退款申请失败: 退款申请失败: 订单已退款' || $e->getMessage() == '[INVALID_REQUEST] 订单已全额退款'){
                Db::name('refund')->where('id', $refundId)->update([
                    'status' => 1, // 退款成功
                    'refund_id' => $refundData['id'] ?? '', // 微信退款单号
                    'update_time' => time(),
                    'refund_status' => '订单已退款', // 退款状态
                    'create_time' => time(), // 微信退款创建时间
                    'out_refund_no' => $refundData['refund_no'] ?? '', // 商户退款单号
                    'out_trade_no' => $order['order_sn'] ?? '', // 商户订单号
                ]);

                // 更新订单状态
                Db::name('order')->where('id', $order_id)->update([
                    'status' => 4, // 已退款
                    'pay_status' => 4, // 已退款
                    'refund_time' => time(),
                    'refund_status' => 'SUCCESS',
                    'refund_amount' => $refund_fee,
                ]);

                // 更新报名项目状态
                if(!empty($apply_item_id)){
                    Db::name('eb_apply_form_item')->where('id', $apply_item_id)->update([
                        'pay_status' => 4, // 退款成功
                        'status' => 0, // 退款成功
                    ]);
                }

                return $this->success('已退过款', $refundData);
            }
            else{
                // 再次查询退款状态
                $refundStatus = $this->queryWechatRefundStatus($refundData['refund_no']);

                if($refundStatus['refund_status'] === 'SUCCESS'){
                    Db::name('refund')->where('id', $refundId)->update([
                        'status' => 1, // 退款成功
                        'refund_id' => $refundStatus['refund_id'] ?? '', // 微信退款单号
                        'update_time' => time(),
                        'refund_status' => $refundStatus['refund_status'], // 退款状态
                        'create_time' => strtotime($refundStatus['create_time']), // 微信退款创建时间
                        'out_refund_no' => $refundStatus['out_refund_no'] ?? '', // 商户退款单号
                        'out_trade_no' => $refundStatus['out_trade_no'] ?? '', // 商户订单号
                        'user_received_account' => $refundStatus['user_received_account'] ?? '', // 用户退款收款账户
                    ]);

                    // 更新订单状态
                    Db::name('order')->where('id', $order_id)->update([
                        'status' => 4, // 已退款
                        'pay_status' => 4, // 已退款
                        'refund_id' => $refundStatus['refund_id'],
                        'refund_time' => time(),
                        'refund_status' => 'SUCCESS',
                        'refund_amount' => $refund_fee,
                    ]);

                    // 更新报名项目状态
                    if(!empty($apply_item_id)){
                        Db::name('eb_apply_form_item')->where('id', $apply_item_id)->update([
                            'pay_status' => 4, // 退款成功
                            'status' => 0, // 退款成功
                        ]);
                    }

                    return $this->success('此订单已经成功退过款', $refundStatus);
                }
                else {
                    Db::name('refund')->where('id', $refundId)->update([
                        'status' => 2, // 退款失败
                        'fail_reason' => $e->getMessage(),
                        'update_time' => time(),
                    ]);

                    if($e->getMessage() == '[INVALID_REQUEST] 申请退款金额超过订单可退金额'){
                        // 向微信查询订单可退金额
                        $orderInfo = $this->queryWechatOrderInfo($order['out_trade_no']);
                        $refundableAmount = $orderInfo['refundable_amount'] / 100; // 转换为元
                        if($orderInfo["trade_state_desc"]=="订单发生过退款，退款详情请查询退款单"){
                            // 查询微信退款详情记录
                            if($refundStatus['refund_status'] === 'SUCCESS'){
                                return $this->success('此订单已经成功退过款', $refundStatus);
                            }

                            $url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds?out_trade_no=' . $order['out_trade_no'];

                            // 加载微信支付配置
                            $wechatConfig = \think\Config::get('wechat');
                            $config = $wechatConfig['payment'] ?? [];

                            if (empty($config)) {
                                throw new \Exception('微信支付配置未找到');
                            }

                            // 发送查询请求
                            $result = $this->requestWechatRefundQuery($url, $config);

                            // 处理返回结果
                            if(isset($result['data']) && !empty($result['data'])){
                                foreach($result['data'] as $refund){
                                    $refundInfo = [
                                        'refund_id' => $refund['refund_id'] ?? '',
                                        'out_refund_no' => $refund['out_refund_no'] ?? '',
                                        'out_trade_no' => $refund['out_trade_no'] ?? '',
                                        'refund_status' => $refund['status'] ?? 'UNKNOWN',
                                        'create_time' => $refund['create_time'] ?? '',
                                        'success_time' => $refund['success_time'] ?? '',
                                        'user_received_account' => $refund['user_received_account'] ?? '',
                                    ];

                                    // 如果有退款金额信息
                                    if(isset($refund['amount'])){
                                        $refundInfo['total'] = $refund['amount']['total'] ?? 0;
                                        $refundInfo['refund'] = $refund['amount']['refund'] ?? 0;
                                        $refundInfo['payer_total'] = $refund['amount']['payer_total'] ?? 0;
                                        $refundInfo['payer_refund'] = $refund['amount']['payer_refund'] ?? 0;
                                    }

                                    $refundList[] = $refundInfo;

                                    if($refundInfo['refund_status'] === 'SUCCESS'){
                                        $hasRefund = true;
                                    }
                                }
                            }
                            return $this->error('退款申请失败: 申请退款金额超过订单可退金额，可退金额为：' . $refundableAmount . '元', null, 500);
                        }
                    }

                    return $this->error('退款申请失败: ' . $e->getMessage(), null, 500);
                }
            }
        }
    }

    /**
     * 查询微信订单信息
     *
     * @param string $outTradeNo 商户订单号
     * @return array 订单信息
     */
    private function queryWechatOrderInfo($outTradeNo) {
        try {
            // 统一读取 wechat.pay 配置
            $config = \think\Config::get('wechat.pay');
            if (empty($config)) {
                throw new \Exception('微信支付配置未找到');
            }

            // 检查必要的配置项
            if (empty($config['merchant_id']) || empty($config['key'])) {
                throw new \Exception('微信支付配置不完整');
            }

            // 查询订单请求URL
            $url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/' . $outTradeNo . '?mchid=' . $config['merchant_id'];

            // 发送查询请求
            $result = $this->requestWechatOrderQuery($url, $config);

            // 返回订单信息，包括可退金额
            return [
                'transaction_id' => $result['transaction_id'] ?? '',
                'out_trade_no' => $result['out_trade_no'] ?? '',
                'trade_state' => $result['trade_state'] ?? '',
                'trade_state_desc' => $result['trade_state_desc'] ?? '',
                'bank_type' => $result['bank_type'] ?? '',
                'success_time' => $result['success_time'] ?? '',
                'amount' => $result['amount'] ?? [],
                'refundable_amount' => isset($result['amount']['refundable_amount']) ? $result['amount']['refundable_amount'] : 0
            ];
        } catch (\Exception $e) {
            throw new \Exception('查询微信订单信息失败: ' . $e->getMessage());
        }
    }

    /**
     * 发送微信订单查询请求
     *
     * @param string $url 请求URL
     * @param array $config 微信支付配置
     * @return array 响应结果
     */
    private function requestWechatOrderQuery($url, $config) {
        $body = '';
        $auth = $this->buildRefundAuth('GET', $url, $body, $config);

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => [
                'Accept: application/json',
                'Content-Type: application/json',
                'User-Agent: FastAdmin/WeChatPay',
                'Authorization: ' . $auth
            ]
        ]);

        $response = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new \Exception("CURL Error: " . $error);
        }

        $result = json_decode($response, true);

        // 微信订单查询接口可能返回200以外的成功状态码，我们只在明确的错误状态码时抛出异常
        if ($status >= 400) {
            $message = isset($result['message']) ? $result['message'] : '微信订单查询接口请求失败';
            $code = isset($result['code']) ? $result['code'] : 'UNKNOWN_ERROR';
            throw new \Exception("[$code] $message");
        }

        return $result;
    }

    /**
     * 处理微信退款
     *
     * @param string $transactionId 微信支付订单号
     * @param string $refundNo 商户退款单号
     * @param float $totalFee 订单金额
     * @param float $refundFee 退款金额
     * @return array 退款结果
     */
    private function processWechatRefund($transactionId, $refundNo, $totalFee, $refundFee) {
        // 统一读取 wechat.pay 配置
        $config = \think\Config::get('wechat.pay');

        if (empty($config)) {
            throw new \Exception('微信支付配置未找到');
        }

        // 检查必要的配置项
        if (empty($config['merchant_id']) && empty($config['mchid'])) {
            throw new \Exception('微信支付商户ID未配置');
        }

        // 退款请求URL
        $url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds';

        // 构造请求数据
        $data = [
            'transaction_id' => $transactionId,
            'out_refund_no' => $refundNo,
            'amount' => [
                'refund' => intval($refundFee * 100), // 退款金额，单位：分
                'total' => intval($totalFee * 100), // 订单金额，单位：分
                'currency' => 'CNY'
            ]
        ];

        // 添加退款原因（如果有）
        if (!empty($this->request->param('refund_reason'))) {
            $data['reason'] = $this->request->param('refund_reason');
        }

        // 发送请求
        $result = $this->requestWechatRefund($data);

        return $result;
    }

    /**
     * 发送微信退款请求
     *
     * @param array $data 请求数据
     * @return array 响应结果
     */
    private function requestWechatRefund($data) {
        // 统一读取 wechat.pay 配置
        $config = \think\Config::get('wechat.pay');

        if (empty($config)) {
            throw new \Exception('微信支付配置未找到');
        }

        // 检查必要的配置项
        if (empty($config['merchant_id']) && empty($config['mchid'])) {
            throw new \Exception('微信支付商户ID未配置');
        }

        // 退款请求URL
        $url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds';

        $body = $data ? json_encode($data, JSON_UNESCAPED_UNICODE) : '';
        $auth = $this->buildRefundAuth('POST', $url, $body, $config);

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => [
                'Accept: application/json',
                'Content-Type: application/json',
                'User-Agent: FastAdmin/WeChatPay',
                'Authorization: ' . $auth
            ]
        ]);

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

        $response = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new \Exception("CURL Error: " . $error);
        }

        $result = json_decode($response, true);

        // 微信退款查询接口可能返回200以外的成功状态码，我们只在明确的错误状态码时抛出异常
        if ($status >= 400) {
            $message = isset($result['message']) ? $result['message'] : '微信退款接口请求失败';
            $code = isset($result['code']) ? $result['code'] : 'UNKNOWN_ERROR';
            throw new \Exception("[$code] $message");
        }

        return $result;
    }

    /**
     * 构造退款请求的Authorization
     *
     * @param string $method HTTP方法
     * @param string $url 请求URL
     * @param string $body 请求体
     * @param array $config 微信支付配置
     * @return string Authorization头
     */
    private function buildRefundAuth($method, $url, $body, $config) {
        // 统一读取 wechat.pay 配置
        $fullConfig = \think\Config::get('wechat.pay');

        $timestamp = time();
        $nonce = uniqid();
        $urlParts = parse_url($url);
        $canonicalUrl = ($urlParts['path'] ?? '/') . (isset($urlParts['query']) ? '?' . $urlParts['query'] : '');

        // 对于GET请求，body应该为空字符串而不是null
        if ($method === 'GET') {
            $body = '';
        }

        $message = $method . "\n" .
            $canonicalUrl . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";

        // 获取私钥路径，支持多种配置名称，并修正路径
        $keyPath = $fullConfig['merchant_private_key_path'] ?? $fullConfig['key_path'] ?? null;
        if (empty($keyPath)) {
            throw new \Exception('微信支付配置中缺少私钥路径配置');
        }

        // 修正证书路径，将wxcert目录改为cert目录
        if (strpos($keyPath, '/wxcert/') !== false) {
            $keyPath = str_replace('/wxcert/', '/cert/', $keyPath);
        }

        // 检查私钥文件是否存在
        if (!file_exists($keyPath)) {
            throw new \Exception('微信支付私钥文件不存在: ' . $keyPath);
        }

        $signature = $this->generateRefundSign($message, $keyPath);

        // 获取商户ID，支持多种配置名称
        $merchantId = $fullConfig['merchant_id'] ?? $fullConfig['mchid'] ?? '';
        if (empty($merchantId)) {
            throw new \Exception('微信支付配置中缺少商户ID');
        }

        // 获取商户证书序列号，支持多种配置名称
        $mchSerialNo = $fullConfig['merchant_serial_no'] ?? $fullConfig['serial_no'] ?? $fullConfig['mch_serial_no'] ?? '5C5D72F82C6A51FCC19C64E0C53661EAF59D7881';

        return sprintf(
            'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $merchantId,
            $nonce,
            $timestamp,
            $mchSerialNo,
            $signature
        );
    }

    /**
     * 生成退款请求签名
     *
     * @param string $message 签名串
     * @param string $keyPath 商户API私钥路径
     * @return string 签名
     */
    private function generateRefundSign($message, $keyPath) {
        // 确保使用正确的证书路径
        if (strpos($keyPath, '/wxcert/') !== false) {
            $keyPath = str_replace('/wxcert/', '/cert/', $keyPath);
        }

        // 检查私钥文件是否存在
        if (!file_exists($keyPath)) {
            throw new \Exception('微信支付私钥文件不存在: ' . $keyPath);
        }

        $privateKey = openssl_pkey_get_private(file_get_contents($keyPath));
        if (!$privateKey) {
            throw new \Exception('无法加载商户API私钥');
        }

        $signature = '';
        if (!openssl_sign($message, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
            throw new \Exception('签名生成失败: ' . openssl_error_string());
        }

        return base64_encode($signature);
    }

    /**
     * 查询微信退款状态
     *
     * @param string $refundNo 商户退款单号
     * @return array 退款状态信息
     */
    private function queryWechatRefundStatus($refundNo) {
        try {
            // 统一读取 wechat.pay 配置
            $config = \think\Config::get('wechat.pay');

            if (empty($config)) {
                throw new \Exception('微信支付配置未找到');
            }

            // 检查必要的配置项
            if (empty($config['merchant_id']) && empty($config['mchid'])) {
                throw new \Exception('微信支付商户ID未配置');
            }

            // 查询退款请求URL
            $url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/' . $refundNo;

            // 构建认证头
            $auth = $this->buildRefundAuth('GET', $url, '', $config);
            $trade=db::name("fa_refund")->alias("r")->join("fa_order o","r.order_id=o.id","left")->where("refund_no","eq",$refundNo)->field("o.out_trade_no")->find();
            $out_trade_no=$trade['out_trade_no'];
            // 发送请求
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_HTTPHEADER => [
                    'Accept: application/json',
                    'Content-Type: application/json',
                    'User-Agent: FastAdmin/WeChatPay',
                    'Authorization: ' . $auth
                ]
            ]);

            $response = curl_exec($ch);
            $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            curl_close($ch);

            if($response=='{"code":"RESOURCE_NOT_EXISTS","message":"退款单不存在"}'){
                $this->queryOrderRefunds($out_trade_no) ;
            }

            if ($error) {
                throw new \Exception("CURL Error: " . $error);
            }

            $result = json_decode($response, true);

            // 微信退款查询接口可能返回200以外的成功状态码，我们只在明确的错误状态码时抛出异常
            if ($status >= 400) {
                $message = isset($result['message']) ? $result['message'] : '微信退款查询接口请求失败';
                $code = isset($result['code']) ? $result['code'] : 'UNKNOWN_ERROR';
                throw new \Exception("[$code] $message");
            }

            // 返回退款状态信息
            return [
                'refund_status' => $result['status'] ?? '',
                'refund_id' => $result['refund_id'] ?? '',
                'out_refund_no' => $result['out_refund_no'] ?? '',
                'amount' => $result['amount'] ?? [],
                'success_time' => $result['success_time'] ?? '',
                'channel' => $result['channel'] ?? '',
                'user_received_account' => $result['user_received_account'] ?? '',
                'refund_account' => $result['refund_account'] ?? '',
                'trade_type' => $result['trade_type'] ?? '',
                'transaction_id' => $result['transaction_id'] ?? '',
                'out_trade_no' => $result['out_trade_no'] ?? '',
                'order_id' => $result['order_id'] ?? '',
                'create_time' => $result['create_time'] ?? '',
                'status' => $result['status'] ?? ''
            ];

        } catch (\Exception $e) {
            // 记录错误日志
            \think\Log::error('查询微信退款状态失败: ' . $e->getMessage());
            throw $e;
        }
    }

    /**
     * 发送微信退款查询请求
     *
     * @param string $url 请求URL
     * @param array $config 微信支付配置
     * @return array 响应结果
     */
    private function requestWechatRefundQuery1($url, $config) {
        $body = '';
        $auth = $this->buildRefundAuth('GET', $url, $body, $config);

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => [
                'Accept: application/json',
                'Content-Type: application/json',
                'User-Agent: FastAdmin/WeChatPay',
                'Authorization: ' . $auth
            ]
        ]);

        $response = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new \Exception("CURL Error: " . $error);
        }

        $result = json_decode($response, true);

        // 微信退款查询接口可能返回200以外的成功状态码，我们只在明确的错误状态码时抛出异常
        if ($status >= 400) {
            $message = isset($result['message']) ? $result['message'] : '微信退款查询接口请求失败';
            $code = isset($result['code']) ? $result['code'] : 'UNKNOWN_ERROR';
            throw new \Exception("[$code] $message");
        }

        return $result;
    }

    public function setCollection(Request $request)
    {
        $user = $this->auth->getUser();
        if(empty($user)){
            return $this->error('请先登录', null, 400);
        }

        $params = $request->param();
        $target_id = $params['target_id'];
        $school_id = $params['school_id'];
        $type = $params['type'];
        $star = $params['star'];
        if(empty($target_id) || empty($school_id) || empty($type)){
            return $this->error('参数不为空', null, 400);
        }
        $data = [
            'user_id' => $user['uid'],
            'target_id' => $target_id,
            'school_id' => $school_id,
            'type' => $type
        ];
        $favorites = Favorites::where($data)->find();
        if (empty($favorites)){
            $result = Favorites::create($data);
        }else{
            $query = Favorites::where($data);
            if ($star){
                $result = $query->update(['delete_time'=> date('Y-m-d H:i:s')]);
            }else{
                $result = $query->update(['update_time'=>date('Y-m-d H:i:s'),'delete_time'=>null]);
            }
        }

        return $this->success('返回成功', $result);
    }

    public function getCollection(Request $request)
    {
        $user = $this->auth->getUser(true);
        if(empty($user)){
            return $this->success('返回成功', 0);
        }

        $params = $request->param();
        $target_id = $params['target_id'];
        $school_id = $params['school_id'];
        $type = $params['type'];
        if(empty($target_id) || empty($school_id) || empty($type)){
            return $this->success('返回成功', 0);
        }
        $data = [
            'user_id' => $user['uid'],
            'target_id' => $target_id,
            'school_id' => $school_id,
            'type' => $type
        ];
        $result = Favorites::where($data)->where('delete_time',null)->find();

        return $this->success('返回成功', empty($result) ? 0 : 1);
    }

    public function getCollectionList(Request $request)
    {
        $user = $this->auth->getUser(true);
        if(empty($user['uid'])){
            //return $this->success('请登录', [], 400);
        }
        $latitude = $request->param('latitude', '22.81000000000000');
        $longitude = $request->param('longitude', '108.35528564453125');

        $where = ['a.user_id'=> $user['uid'], 'a.delete_time'=> null, 'a.type'=> 0];
        $data[] = Favorites::alias('a')->join('eb_school b','a.target_id=b.id')->where($where)
            ->order('a.update_time','desc')
            ->field('b.id,b.is_official,b.name,b.school_logo')
            ->select();

        $where['a.type'] = 1;
        $data[] = Favorites::alias('a')->join('fa_ocation b','a.target_id=b.id')->where($where)
            ->order('a.update_time','desc')
            ->field('b.id,b.name,b.cover')
            ->select();

        $where['a.type'] = 2;
        $classes = Favorites::alias('a')->join('eb_classes b','a.target_id=b.id')->where($where)
            ->order('a.update_time','desc')
            ->field('b.id,b.name,b.cover,b.create_time,b.price,b.classes_type')
            ->select();

        foreach ($classes as $k => $v) {
            $tags = []; // 初始化$tags数组

            // 设置默认值
            $classes[$k]['km'] = null;
            $classes[$k]['ocation_name'] = '';
            $classes[$k]['octionlevel'] = '';

            $ocation_id = Db::name('course_table_autoplan_temp')->where('classes_id', $v['id'])->value('ocation_id');
            if ($ocation_id) {
                $ocation = Ocation::where('id', $ocation_id)
                    ->field('longitude,latitude,name,address_lv_octionlevel')
                    ->find();

                if ($v['classes_type'] === 2 && $ocation) {
                    $ocation_pid = $ocation['pid'] ?? null;
                    if ($ocation_pid) {
                        $ocation = Ocation::where('id', $ocation_pid)
                            ->field('longitude,latitude,name,address_lv_octionlevel')
                            ->find();
                    }
                }

                if ($ocation) {
                    $locationLat = $ocation['latitude'] ?? 0;
                    $locationLng = $ocation['longitude'] ?? 0;
                    $classes[$k]['km'] = calculateDistance($latitude, $longitude, $locationLat, $locationLng);
                    $classes[$k]['ocation_name'] = $ocation['name'] ?? '';
                    $classes[$k]['octionlevel'] = ($ocation['address_lv_octionlevel'] ?? 0) === 1 ? '一级教学点' : '二级教学点';
                }
            }

            if ($v['classes_type'] === 2) {
                $tags[] = '社区';
            }
            $tags[] = '积分兑换';
            $classes[$k]['tags'] = $tags;
        }

        $data[] = $classes;

        $where['a.type'] = 3;
        $data[] = Favorites::alias('a')->join('fa_article b','a.target_id=b.id')->where($where)
            ->order('a.update_time','desc')
            ->field('b.id,b.title,b.cover,b.create_time,b.likes,b.views')
            ->select();

        return $this->success('获取成功', $data);
    }
    public function delCollection(Request $request)
    {
        $user = $this->auth->getUser();
        if(empty($user['uid'])){
            return $this->error('请登录', [], 400);
        }

        $type = $request->param('type');
        $id = $request->param('id');
        if(empty($id)){
            return $this->error('删除id不为空', [], 400);
        }

        return $this->success('删除成功',
            Favorites::where('target_id',$id)
                ->where('user_id',$user['uid'])
                ->where('type',$type)
                ->update(['delete_time'=> date('Y-m-d H:i:s')])
        );
    }

    /**
     * 获取用户的退款记录
     */
    public function getRefundRecords()
    {
        $user = $this->auth->getUser(true);
        if(empty($user)){
            return $this->error('请先登录', null, 401);
        }

        // 获取用户的退款记录
        $refundRecords = Db::name('refund')
            ->where('user_id', $user['uid'])
            ->order('create_time', 'desc')
            ->select();

        // 格式化数据
        foreach ($refundRecords as &$record) {
            $record['create_time_text'] = $record['create_time'] ? date('Y-m-d H:i:s', $record['create_time']) : '';
            $record['update_time_text'] = $record['update_time'] ? date('Y-m-d H:i:s', $record['update_time']) : '';

            // 获取关联的订单信息
            $order = Db::name('order')
                ->where('id', $record['order_id'])
                ->find();

            if ($order) {
                $record['order_sn'] = $order['order_sn'];
                $record['order_amount'] = $order['amount'];
            }

            // 获取关联的报名项目信息
            $applyItem = Db::name('eb_apply_form_item')
                ->alias('f')
                ->join("eb_classes c", "f.classes_id = c.id", "left")
                ->where('f.order_id', $record['order_id'])
                ->field('f.*, c.name as class_name')
                ->find();

            if ($applyItem) {
                $record['class_name'] = $applyItem['class_name'];
            }

            // 状态文本
            $statusText = [
                0 => '处理中',
                1 => '成功',
                2 => '失败',
                3 => '处理中'
            ];
            $record['status_text'] = $statusText[$record['status']] ?? '未知';
        }

        return $this->success('获取退款记录成功', $refundRecords);
    }

    /**
     * 退款回调处理
     *
     * @param int $order_id 订单ID
     * @param array $refundData 退款数据
     * @return bool 处理结果
     */
    function refundcallback($order_id, $refundData){
        try {
            // 记录日志
            Log::info('退款回调处理开始', [
                'order_id' => $order_id,
                'refund_data' => $refundData
            ]);

            // 查询订单信息
            $order = Db::name('order')->where('id', $order_id)->find();
            if (!$order) {
                Log::error('退款回调处理失败：订单不存在', ['order_id' => $order_id]);
                return false;
            }

            // 查询退款记录
            $refund = Db::name('refund')->where('order_id', $order_id)->find();
            if (!$refund) {
                Log::error('退款回调处理失败：退款记录不存在', ['order_id' => $order_id]);
                return false;
            }

            // 根据退款状态处理
            if ($refundData['refund_status'] == 'SUCCESS') {
                // 退款成功，更新订单状态
                Db::name('order')->where('id', $order_id)->update([
                    'status' => 4, // 已退款
                    'pay_status' => 4, // 已退款
                    'refund_id' => $refundData['refund_id'] ?? '',
                    'refund_time' => time(),
                    'refund_status' => 'SUCCESS',
                    'refund_amount' => $refundData['refund_fee'] ?? $refund['refund_fee'],
                ]);

                // 更新退款记录状态
                Db::name('refund')->where('id', $refund['id'])->update([
                    'status' => 1, // 退款成功
                    'refund_id' => $refundData['refund_id'] ?? '',
                    'update_time' => time(),
                    'refund_status' => 'SUCCESS',
                ]);

                // 更新报名项目状态
                if (!empty($refund['apply_item_id'])) {
                    Db::name('eb_apply_form_item')->where('id', $refund['apply_item_id'])->update([
                        'pay_status' => 4, // 退款成功
                        'status' => 0, // 退款成功
                    ]);
                }

                Log::info('退款回调处理成功：退款成功', [
                    'order_id' => $order_id,
                    'refund_id' => $refundData['refund_id'] ?? ''
                ]);

                return true;
            } else if ($refundData['refund_status'] == 'PROCESSING') {
                // 退款处理中，更新退款记录状态
                Db::name('refund')->where('id', $refund['id'])->update([
                    'status' => 3, // 退款处理中
                    'refund_id' => $refundData['refund_id'] ?? '',
                    'update_time' => time(),
                    'refund_status' => 'PROCESSING',
                ]);

                Log::info('退款回调处理成功：退款处理中', [
                    'order_id' => $order_id,
                    'refund_id' => $refundData['refund_id'] ?? ''
                ]);

                return true;
            } else if ($refundData['refund_status'] == 'FAILED') {
                // 退款失败，更新退款记录状态
                Db::name('refund')->where('id', $refund['id'])->update([
                    'status' => 2, // 退款失败
                    'refund_id' => $refundData['refund_id'] ?? '',
                    'update_time' => time(),
                    'refund_status' => 'FAILED',
                    'fail_reason' => $refundData['fail_reason'] ?? '退款失败',
                ]);

                Log::info('退款回调处理成功：退款失败', [
                    'order_id' => $order_id,
                    'refund_id' => $refundData['refund_id'] ?? '',
                    'fail_reason' => $refundData['fail_reason'] ?? '退款失败'
                ]);

                return true;
            } else {
                Log::error('退款回调处理失败：未知退款状态', [
                    'order_id' => $order_id,
                    'refund_status' => $refundData['refund_status'] ?? ''
                ]);

                return false;
            }
        } catch (\Exception $e) {
            Log::error('退款回调处理异常', [
                'order_id' => $order_id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return false;
        }
    }

    /**
     * 完成退款
     */
    private function finishRefund($refundId, $refundStatus, $order_id, $apply_item_id, $refund_fee)
    {
        Db::name('refund')->where('id', $refundId)->update([
            'status' => 1, // 退款成功
            'refund_id' => $refundStatus['refund_id'] ?? '', // 微信退款单号
            'update_time' => time(),
            'refund_status' => $refundStatus['refund_status'], // 退款状态
            'create_time' => strtotime($refundStatus['create_time']), // 微信退款创建时间
            'out_refund_no' => $refundStatus['out_refund_no'] ?? '', // 商户退款单号
            'out_trade_no' => $refundStatus['out_trade_no'] ?? '', // 商户订单号
            'user_received_account' => $refundStatus['user_received_account'] ?? '', // 用户退款收款账户
        ]);

        // 更新订单状态
        Db::name('order')->where('id', $order_id)->update([
            'status' => 4, // 已退款
            'pay_status' => 4, // 已退款
            'refund_id' => $refundStatus['refund_id'],
            'refund_time' => time(),
            'refund_status' => 'SUCCESS',
            'refund_amount' => $refund_fee,
        ]);

        // 更新报名项目状态
        if(!empty($apply_item_id)){
            Db::name('eb_apply_form_item')->where('id', $apply_item_id)->update([
                'pay_status' => 4, // 退款成功
                'status' => 0, // 退款成功
            ]);
        }
        return true;
    }

    /**
     * 查询订单的退款信息（不需要退款单号）
     *
     * @param string $order_id 订单ID或订单号
     * @return array 退款信息
     */
    public function queryOrderRefunds($out_trade_no = '')
    {
        $user = $this->auth->getUser(true);
        if(empty($user)){
            return $this->error('请先登录', null, 401);
        }


        if(empty($out_trade_no)){
            return $this->error('请提供订单ID或订单号', null, 400);
        }

        try {
            // 根据提供的参数查询订单信息
            if(!empty($out_trade_no)){
                $order = Db::name('fa_order')->where('out_trade_no', $out_trade_no)->find();
            }

            if(!$order){
                return $this->error('订单信息不存在', null, 404);
            }

            // 检查订单是否属于当前用户
            $applyItem = Db::name('eb_apply_form_item')->where('order_id', $order['id'])->find();
            if($applyItem && $applyItem['user_id'] != $user['uid']){
                return $this->error('无权查询此订单信息', null, 403);
            }

            // 查询该订单的所有退款记录
            $refundRecords = Db::name('refund')->where('order_id', $order['id'])->select();

            $refundList = [];
            $hasRefund = false;

            // 如果有退款记录，查询每个退款的状态
//            if(!empty($refundRecords)){
//                foreach($refundRecords as $refund){
//                    $refundInfo = $this->queryWechatRefundStatus($refund['refund_no']);
//                    $refundInfo['local_refund_id'] = $refund['id'];
//                    $refundInfo['local_status'] = $refund['status'];
//                    $refundInfo['local_create_time'] = $refund['create_time'];
//                    $refundInfo['local_update_time'] = $refund['update_time'];
//                    $refundInfo['local_fail_reason'] = $refund['fail_reason'];
//
//                    $refundList[] = $refundInfo;
//
//                    if($refundInfo['refund_status'] === 'SUCCESS'){
//                        $hasRefund = true;
//                    }
//                }
//            } else {
            // 没有退款记录，查询微信支付系统是否有退款记录
            try {
                // 先查询订单信息，获取可退金额
                $orderInfo = $this->queryWechatOrderInfo($order['out_trade_no']);

                // 如果订单状态描述为"订单发生过退款"，则查询退款记录
                if($orderInfo['trade_state_desc'] == '订单发生过退款，退款详情请查询退款单'){
                    // 使用微信支付查询接口查询退款记录
                    $url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds?out_trade_no=' . $order['out_trade_no'];

                    // 加载微信支付配置
                    $wechatConfig = \think\Config::get('wechat');
                    $config = $wechatConfig['payment'] ?? [];

                    if (empty($config)) {
                        throw new \Exception('微信支付配置未找到');
                    }

                    // 发送查询请求
                    $result = $this->requestWechatRefundQuery($url, $config);

                    // 处理返回结果
                    if(isset($result['data']) && !empty($result['data'])){
                        foreach($result['data'] as $refund){
                            $refundInfo = [
                                'refund_id' => $refund['refund_id'] ?? '',
                                'out_refund_no' => $refund['out_refund_no'] ?? '',
                                'out_trade_no' => $refund['out_trade_no'] ?? '',
                                'refund_status' => $refund['status'] ?? 'UNKNOWN',
                                'create_time' => $refund['create_time'] ?? '',
                                'success_time' => $refund['success_time'] ?? '',
                                'user_received_account' => $refund['user_received_account'] ?? '',
                            ];

                            // 如果有退款金额信息
                            if(isset($refund['amount'])){
                                $refundInfo['total'] = $refund['amount']['total'] ?? 0;
                                $refundInfo['refund'] = $refund['amount']['refund'] ?? 0;
                                $refundInfo['payer_total'] = $refund['amount']['payer_total'] ?? 0;
                                $refundInfo['payer_refund'] = $refund['amount']['payer_refund'] ?? 0;
                            }

                            $refundList[] = $refundInfo;

                            if($refundInfo['refund_status'] === 'SUCCESS'){
                                $hasRefund = true;
                            }
                        }
                    }
                }
            } catch (\Exception $e) {
                // 查询微信退款记录失败，记录日志但不影响返回
                Log::error('查询微信退款记录失败: ' . $e->getMessage());
                // 不再使用exit，而是继续执行
            }
//            }

            // 返回订单信息和退款记录
            return $this->success('查询成功', [
                'order_id' => $order['id'],
                'order_sn' => $order['order_sn'],
                'out_trade_no' => $order['out_trade_no'],
                'amount' => $order['amount'],
                'pay_status' => $order['pay_status'],
                'refund_status' => $order['refund_status'],
                'has_refund' => $hasRefund,
                'refund_list' => $refundList
            ]);

        } catch (\Exception $e) {
            return $this->error('查询失败: ' . $e->getMessage(), null, 500);
        }
    }

    /**
     * 发送微信退款查询请求
     */
    private function requestWechatRefundQuery($url, $config)
    {
        // 生成签名
        $method = 'GET';
        $urlParts = parse_url($url);
        $canonicalUrl = $urlParts['path'] . ($urlParts['query'] ? '?' . $urlParts['query'] : '');
        $timestamp = time();
        $nonce = uniqid(); // 修改为与buildRefundAuth一致

        // 构建签名消息
        $message = $method . "\n" . $canonicalUrl . "\n" . $timestamp . "\n" . $nonce . "\n" . "\n";

        // 加载私钥
        $privateKeyPath = $config['key_path'] ?? ''; // 使用key_path而不是private_key_path
        if (!file_exists($privateKeyPath)) {
            throw new \Exception('私钥文件不存在: ' . $privateKeyPath);
        }

        $privateKey = file_get_contents($privateKeyPath);

        // 生成签名
        $signature = '';
        if (!openssl_sign($message, $signature, $privateKey, 'sha256WithRSAEncryption')) {
            throw new \Exception('签名生成失败');
        }
        $signature = base64_encode($signature);

        // 构建Authorization头 - 修改为与buildRefundAuth一致
        $authorization = 'WECHATPAY2-SHA256-RSA2048 ' .
            'mchid="' . $config['merchant_id'] . '",' . // 使用merchant_id而不是mch_id
            'nonce_str="' . $nonce . '",' .
            'timestamp="' . $timestamp . '",' .
            'signature="' . $signature . '",' .
            'serial_no="' . ($config['serial_no'] ?? '') . '"'; // 使用serial_no而不是certificate_serial_no

        // 记录请求信息
        Log::info('微信退款查询请求', [
            'url' => $url,
            'method' => $method,
            'canonicalUrl' => $canonicalUrl,
            'timestamp' => $timestamp,
            'nonce' => $nonce,
            'message' => $message,
            'authorization' => $authorization
        ]);

        // 发送请求
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: ' . $authorization,
            'Accept: application/json',
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        // 记录响应信息
        Log::info('微信退款查询响应', [
            'httpCode' => $httpCode,
            'response' => $response,
            'error' => $error
        ]);

        if ($httpCode >= 200 && $httpCode < 300) {
            $result = json_decode($response, true);
            return $result;
        } else {
            // 尝试解析错误响应
            $errorData = json_decode($response, true);
            $errorMessage = '请求失败，HTTP状态码: ' . $httpCode;

            if ($errorData && isset($errorData['message'])) {
                $errorMessage .= ', 错误信息: ' . $errorData['message'];
            }

            if (!empty($error)) {
                $errorMessage .= ', cURL错误: ' . $error;
            }

            throw new \Exception($errorMessage);
        }
    }
}
?>
